package express.compiler;

import com.google.common.collect.Lists;
import express.Regexs;
import express.bttree.Operator;
import express.bttree.Utils;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;

import java.util.List;
import java.util.regex.Matcher;

@Data
public class MethodInfo {
    private String methodName;
    private List<Object> params;
    private Operator op;
    private Object result;

    private static Object convertValue(Object param) {
        String sParam = param.toString();
        Matcher matcher = Regexs.STRING_REG.matcher(sParam);
        if(matcher.find()) {
            return matcher.group(2);
        } else {
            if(StringUtils.equalsAnyIgnoreCase(sParam,"true","false")) {
                return Boolean.parseBoolean(sParam);
            } else {
                if(StringUtils.isNumeric(sParam)) {
                    if(NumberUtils.isDigits(sParam)) {
                        long longVal = Long.parseLong(sParam);
                        if(longVal > Integer.MAX_VALUE) {
                            return longVal;
                        } else {
                            return (int) longVal;
                        }
                    } else {
                        double doubleVal = Double.parseDouble(sParam);
                        if(doubleVal > Float.MAX_VALUE) {
                            return doubleVal;
                        } else {
                            return (float)doubleVal;
                        }
                    }
                } else {
                    throw new RuntimeException("参数错误，params:" + param);
                }
            }
        }
    }

    public static MethodInfo convert(List<SyntaxNode> syntaxNodes) {
        if(syntaxNodes.size() == 0) {
            throw new RuntimeException("列表不能为空");
        }
        String methodName = syntaxNodes.get(0).getValue();
        List<Object> params = Lists.newArrayList();
        Operator operator = null;
        List<Object> results = Lists.newArrayList();
        for (int i = 1; i < syntaxNodes.size(); i++) {
            SyntaxNode syntaxNode = syntaxNodes.get(i);
            if(operator == null) {
                Operator op = Utils.getOperator(syntaxNode.getValue());
                if(op != null) {
                    operator = op;
                } else {
                    params.add(convertValue(syntaxNode.getValue()));
                }
                continue;
            }
            results.add(syntaxNode.getValue());
        }

        MethodInfo methodInfo = new MethodInfo();
        methodInfo.setMethodName(methodName);
        methodInfo.setParams(params);
        if(operator != null) {
            methodInfo.setOp(operator);
            if(results.size() != 1) {
                throw new RuntimeException("结果错误，" + results);
            } else {
                methodInfo.setResult(convertValue(results.get(0)));
            }
        } else {
            if(!results.isEmpty()) {
                throw new RuntimeException("结果错误，" + results);
            } else {
                methodInfo.setOp(Operator.eq);
                methodInfo.setResult(true);
            }
        }
        return methodInfo;

    }
}
